
/*
Axios 封装
处理token header


*/

import axios from 'axios'
import { getStore, setStore,removeStore } from './storage'
import { Message, Loading } from 'element-ui'
import Cookies from 'js-cookie'
// import {v4 as uuidv4} from 'uuid'
import router from '../router/index'
import { getKey, getAesKey } from "./key.js"
import {aes,md5} from './utils'

const publicKey = import.meta.env.VITE_KEY_HTTP
// var publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeCDcnFrS7DIRbvZLHreVUzaMbAFy2DYmioxBK606urY4rVR8IgLgUhnyw2/GQ99pyr8lGtqPeOoapantw1XwEVyi74MDxs4UDL8j4OZR1Es7HVGOB0GwKWobdU9cm/1iDwGyouSmijxKyAePg6KsLNgbjDPYZRS11bYEuZ8/RLQIDAQAB/8008D6C4DB52407FA89761C10A391F21';

// 统一请求路径前缀
// export const baseUrl = GetNodeEnv();
export const baseUrl = import.meta.env.VITE_BASE_URL


function GetNodeEnv() {
  if (process.env.NODE_ENV === 'development') {
    return 'https://star.labsci.com.cn/';
  } else {
    return 'https://star.labsci.com.cn/';
  }
}

// 统一加解密
const Unify = {
  // 统一加密方法
  en(data, key) {
    // 1.Md5加密
    let md5Str = md5(data);
    return md5Str;
    //let aesStr = aes(JSON.stringify(data), key);
    //return aesStr;
  },
  // 统一解密
  de(aesStr, key) {
    // 1.aes解密
    let dataStr = md5(aesStr, key);
    // 3.转json对象
    let data = JSON.parse(dataStr);
    return data;
  },
};


export const commonUrl = ''
// 文件上传接口
export const uploadFile = commonUrl + '/common/common/upload/file'
var isRefreshToken = 0
const refreshToken = getTokenDebounce()
const service = axios.create({
  timeout: 15000,
  baseURL: baseUrl
})
service.interceptors.request.use(
  config => {
    if (config.method == 'get') {
      // config.params = {
      //   _t: Date.parse(new Date()) / 1000,
      //   ...config.params
      // }
    }
    const contenttype = config.headers["Accept"];
    //let types = contenttype.includes("application/json");
    let key = getKey(); // 获取密钥

    const timestamp = new Date().getTime();//时间戳
    let dataJm = Unify.en(timestamp+publicKey, key.key); //加密 Md5
    //config.headers["selectKey"] = key.code; // 将 aes 的 code 设置到请求头,传给后端解密
    config.headers["timestamp"] = timestamp;
    config.headers["selectKey"] = dataJm;
    //post方式
    // if (types) {
    //     if (config.data) {
    //       config.headers["crypto"] = true;
    //       config.headers["content-type"] = "application/json";
    //       let data = {
    //         body: config.data,
    //       };
    //       let dataJm = Unify.en(data, key.key); // 加密 post 请求参数
    //       config.headers["data"] = dataJm;
    //     }
    // }

    config.headers["Authorization"] = 'Bearer '+getStore('accessToken')
    config.headers["If-Modified-Since"] = "0"
    config.headers["Cache-Control"] = "no-cache"
    // let uuid = getStore('uuid')
    // if (!uuid) {
    //   uuid = uuidv4()
    //   setStore('uuid', uuid)
    // }
    //  config.headers['uuid'] = uuid
    //  console.log("*************************");
    //  console.log(config);
    return config
  },
  err => {
    Message.error('请求超时')
    return Promise.resolve(err)
  }
)

// 全局加载
let loading        //定义loading变量
function startLoading() {    //使用Element loading-start 方法
  // loading = Loading.service({
  //     lock: true,
  //     text: '加载中……',
  //     background: 'rgba(0, 0, 0, 0.7)'
  // })
}
function endLoading() {    //使用Element loading-close 方法
  // loading.close()
}
//那么 showFullScreenLoading() tryHideFullScreenLoading() 要干的事儿就是将同一时刻的请求合并。
//声明一个变量 needLoadingRequestCount，每次调用showFullScreenLoading方法 needLoadingRequestCount + 1。
//调用tryHideFullScreenLoading()方法，needLoadingRequestCount - 1。needLoadingRequestCount为 0 时，结束 loading。
let needLoadingRequestCount = 0
export function showFullScreenLoading() {
  if (needLoadingRequestCount === 0) {
    startLoading()
  }
  needLoadingRequestCount++
}
export function tryHideFullScreenLoading() {
  if (needLoadingRequestCount <= 0) return
  needLoadingRequestCount--
  if (needLoadingRequestCount === 0) {
    endLoading()
  }
}

//http request 拦截器  载入时显示login
service.interceptors.request.use(
  config => {
    // console.log("login")
    // showFullScreenLoading()
    return config;
  },
  error => {
    return Promise.reject(err);
  }
);
// http response 拦截器
service.interceptors.response.use(
  response => {
    const data = response.data
    // 根据返回的code值来做不同的处理(和后端约定)
    if (!data.success && data.message) {
      // Message.error(data.message)
    }
    // 加载完成隐藏login
    // tryHideFullScreenLoading()
    switch (data.code) {
      case 4003:
        // 缓存Token
        removeStore('accessToken')
        removeStore('loginId')
        removeStore('webId')
        removeStore('cusId')
        removeStore('cusName')
        removeStore('typeId')
        removeStore('cusNo')
        removeStore('ifAuditStaff')
        removeStore('ifMaster')
        removeStore('ifPost')
        if (data.message !== null) {
          Message.error("登陆已过期")
          router.push('/login')
        } else {
          Message.error("登陆已过期")
          router.push('/login')
        }
        break
      case 4001:
        // 缓存账号密码
        removeStore('rusername')
        removeStore('rpassword')
        // 缓存Token
        removeStore('accessToken')
        removeStore('loginId')
        removeStore('webId')
        removeStore('cusId')
        removeStore('cusName')
        removeStore('typeId')
        removeStore('cusNo')
        removeStore('ifAuditStaff')
        removeStore('ifMaster')
        removeStore('ifPost')
        if (data.message !== null) {
          Message.error("登陆已过期")
          router.push('/login')
        } else {
          Message.error('系统异常')
          router.push('/login')
        }
        break
      default:
        return data
    }
  },
  async error => {
    // 返回状态码不为200时候的错误处理
    if (error.response) {
      if (error.response.status === 401) {
        // 这种情况一般调到登录页
      } else if (error.response.status === 404) {
        // 避免刷新token报错
      } else if (error.response.status === 403) {
        isRefreshToken++
        if (isRefreshToken === 1) {
          const getTokenRes = await refreshToken()
          if (getTokenRes === 'success') {
            // 刷新token
            if (isRefreshToken === 1) {
              error.response.config.headers.accessToken = getStore(
                'accessToken'
              )
              return service(error.response.config)
            } else {
              router.go(0)
            }
          } else {
            Cookies.set('userInfoSeller', '')
            router.push('/login')
          }
          isRefreshToken = 0
        }
      } else {
        // 其他错误处理
        Message.error(error.response.data.message)
      }
    }

    /* router.push("/login") */
    return Promise.resolve(error)
  }
)

// 防抖闭包来一波
function getTokenDebounce() {
  let lock = false
  let success = false
  return function () {
    if (!lock) {
      lock = true
        .then(res => {
          if (res.success) {
            let { accessToken, refreshToken } = res.result
            setStore('accessToken',  "Bearer ".concat( accessToken))
            setStore('refreshToken', refreshToken)

            success = true
            lock = false
          } else {
            success = false
            lock = false
            // router.push('/login')
          }
        })
        .catch(err => {
          success = false
          lock = false
        })
    }
    return new Promise(resolve => {
      // 一直看lock,直到请求失败或者成功
      const timer = setInterval(() => {
        if (!lock) {
          clearInterval(timer)
          if (success) {
            resolve('success')
          } else {
            resolve('fail')
          }
        }
      }, 500) // 轮询时间间隔
    })
  }
}


/**
 * 无需token验证的请求 避免旧token过期导致请求失败
 * @param {*} url
 * @param {*} params
 */
export const postRequestWithNoTokenData = (url, params) => {
  var data = JSON.stringify(params)
  return service({
    method: 'post',
    url: `${url}`,
    headers: {
      'Content-Type': 'application/json'
    },
    data: data
  })
}

export const getRequest = (url, params, resBlob) => {
  let accessToken = getStore('accessToken')
  let data = {
    method: 'get',
    url: `${url}`,
    params: params,
    headers: {
      Authorization: accessToken
    },
    responseType: 'blob'
  }
  if (resBlob != 'blob') {
    delete data.responseType
  }
  return service(data)
}

export const postRequest = (url, params, headers) => {
  let accessToken = getStore('accessToken')
  return service({
    method: 'post',
    url: `${url}`,
    data: params,
    transformRequest: headers
      ? undefined
      : [
        function (data) {
          let ret = ''
          for (let it in data) {
            ret +=
              encodeURIComponent(it) +
              '=' +
              encodeURIComponent(data[it]) +
              '&'
          }
          ret = ret.substring(0, ret.length - 1)
          return ret
        }
      ],
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: accessToken,
      ...headers
    }
  })
}

/** 不带form表单不带transformRequest */
export const postRequestWithNoForm = (url, params) => {
  let accessToken = getStore('accessToken')
  var data = JSON.stringify(params)
  return service({
    method: 'post',
    url: `${url}`,
    data: data,

    headers: {
      Authorization: accessToken
    }
  })
}

export const postRequestWithHeaders = (url, params) => {
  let accessToken = getStore('accessToken')
  var data = JSON.stringify(params)
  return service({
    method: 'post',
    url: `${url}`,
    data: data,
    headers: {
      Authorization: accessToken,
      'Content-Type': 'application/json'
    }
  })
}

export const putRequestWithHeaders = (url, params) => {
  let accessToken = getStore('accessToken')
  return service({
    method: 'put',
    url: `${url}`,
    data: params,
    headers: {
      Authorization:  accessToken,
      'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
    }
  })
}

export const putRequestWithHeadersJson = (url, params) => {
  let accessToken = getStore('accessToken')
  var data = JSON.stringify(params)
  return service({
    method: 'put',
    url: `${url}`,
    data: data,
    headers: {
      Authorization: accessToken,
      'Content-Type': 'application/json'
    }
  })
}

export const putRequestWithHeadersNotToken = (url, params) => {
  return service({
    method: 'put',
    url: `${url}`,
    data: params,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
    }
  })
}
export const deleteRequestWithHeaders = (url, params) => {
  let accessToken = getStore('accessToken')
  return service({
    method: 'delete',
    url: `${url}`,
    data: params,
    headers: {
      Authorization:  accessToken,
      'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
    }
  })
}

export const putRequest = (url, params, headers) => {
  let accessToken = getStore('accessToken')
  return service({
    method: 'put',
    url: `${url}`,
    data: params,
    transformRequest: headers
      ? undefined
      : [
        function (data) {
          let ret = ''
          for (let it in data) {
            ret +=
              encodeURIComponent(it) +
              '=' +
              encodeURIComponent(data[it]) +
              '&'
          }
          ret = ret.substring(0, ret.length - 1)
          return ret
        }
      ],
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization:  accessToken,
      ...headers
    }
  })
}

export const putRequestWithNoForm = (url, params) => {
  let accessToken = getStore('accessToken')
  return service({
    method: 'put',
    url: `${url}`,
    data: params,

    headers: {
      Authorization: accessToken
    }
  })
}

export const deleteRequest = (url, params) => {
  let accessToken = getStore('accessToken')
  return service({
    method: 'delete',
    url: `${url}`,
    params: params,
    headers: {
      Authorization: accessToken
    }
  })
}

export const importRequest = (url, params) => {
  let accessToken = getStore('accessToken')
  var data = JSON.stringify(params)
  return service({
    method: 'post',
    url: `${url}`,
    data: data,
    headers: {
      Authorization: accessToken
    }
  })
}

export const uploadFileRequest = (url, params) => {
  let accessToken = getStore('accessToken')
  var data = JSON.stringify(params)
  return service({
    method: 'post',
    url: `${url}`,
    data: data,
    headers: {
      Authorization:  accessToken,
      'Content-Type': 'multipart/form-data'
    }
  })
}

/**
 * 无需token验证的请求 避免旧token过期导致请求失败
 * @param {*} url
 * @param {*} params
 */
export const getRequestWithNoToken = async (url, params) => {
  return await service({
    method: 'get',
    url: `${url}`,
    params: params
  })
}

/**
 * 无需token验证的请求 避免旧token过期导致请求失败
 * @param {*} url
 * @param {*} params
 */
export const postRequestWithNoToken = (url, params) => {
  return service({
    method: 'post',
    url: `${url}`,
    params: params
  })
}






export const postRequestWithNoTokenDataFile = (url, params) => {
  return service({
    method: "post",
    url: `${url}`,
    headers: {
      "Content-Type": "multipart/form-data",
    },
    data: params,
  });
}


